import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import {
  ValidatorConstraint,
  ValidationArguments,
  ValidationOptions,
  registerDecorator,
  ValidatorConstraintInterface,
} from 'class-validator';
import { Repository } from 'typeorm';
import { User } from '../entities/user.entity';

@Injectable()
@ValidatorConstraint({ name: 'IsUsernameUnique', async: true })
export class IsUsernameUniqueConstraint
  implements ValidatorConstraintInterface
{
  constructor(@InjectRepository(User) protected repository: Repository<User>) {}
  validate = async (value: any, validationArguments?: ValidationArguments) => {
    console.log(this.repository, 'repositoryrepository');
    //查看数据库是否有些用户名的记录
    const result = await this.repository.findOneBy({ username: value });
    return !result;
  };
  defaultMessage?(validationArguments?: ValidationArguments): string {
    const { value, property } = validationArguments;
    return `${property} ${value} is already exist`;
  }
}

export function IsUsernameUnique(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName, // 目标属性名
      options: validationOptions, //验证选项
      validator: IsUsernameUniqueConstraint, //使用哪个验证器类
    });
  };
}

@Injectable()
@ValidatorConstraint({ name: 'startsWith', async: false })
class StartWithConstraint {
  validate(
    value: any,
    validationArguments?: ValidationArguments,
  ): Promise<boolean> | boolean {
    const { constraints } = validationArguments;
    return value.startsWith(constraints[0]);
  }
  defaultMessage?(validationArguments?: ValidationArguments): string {
    const { constraints, property } = validationArguments;
    return `${property} menu start with ${constraints[0]}`;
  }
}

export function startsWith(
  prefix: string,
  validationOptions?: ValidationOptions,
) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName, // 目标属性名
      options: validationOptions, //验证选项
      constraints: [prefix], //传递给验证器的参数
      validator: StartWithConstraint, //使用哪个验证器类
    });
  };
}
